package com.ytd.smartcanteen.weighting.fragment;

import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.view.View;

import androidx.annotation.NonNull;

import com.ytd.common.util.FormatUtil;
import com.ytd.common.util.LogUtil;
import com.ytd.common.util.YtdConfig;
import com.ytd.smartcanteen.weighting.bean.MealInfo;
import com.ytd.smartcanteen.weighting.bean.OrderBean;
import com.ytd.smartcanteen.weighting.bean.response.GetConsumeResponse;
import com.ytd.smartcanteen.weighting.devices.LEDManager;
import com.ytd.smartcanteen.weighting.devices.ScaleManager;
import com.ytd.smartcanteen.weighting.util.ConsumeNetUtil;
import com.ytd.smartcanteen.weighting.util.ConsumeWarnUtil;
import com.ytd.smartcanteen.weighting.util.MealInfoUtil;
import com.ytd.smartcanteen.weighting.util.WeightConfig;

import org.jetbrains.annotations.Nullable;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Locale;

import cn.ytd.smartcanteen.weighting.R;
import cn.ytd.smartcanteen.weighting.databinding.FragmentConsumeBinding;

/**
 * Your class notes
 *
 * @author gaoguanchao
 * @since 2023/4/18
 */
public class ConsumeFragment extends BaseFragment {
    public final static BigDecimal multiplyValue = new BigDecimal(1000);
    private MealInfo mMealInfo;
    private GetConsumeResponse mConsumeResponse;
    private String mTrayId;
    private boolean isLocal;
    private boolean timeout;

    private FragmentConsumeBinding mBinding;
    private BigDecimal mStableWeight;
    private BigDecimal mTempWeight;
    private long startTime;
    private long endTime;

    private boolean isWhetherLimitWeightOfTake = false;

    private BigDecimal clipWeight;
    private BigDecimal maxClipWeight;
    private BigDecimal minClipWeight;
    private boolean isTakeClip;

    private boolean calPriceStable;
    private boolean calPriceSub;
    private long calPriceTime;
    private long calTime;

    private boolean isClipRoll;

    @Override
    protected void initData(View view) {
        refreshUi();
    }

    @Override
    protected void initView(View view) {
        mBinding = FragmentConsumeBinding.bind(view);
        mBinding.tvClipHintTop.setTextSpeed(2);//设置速度
        mBinding.tvClipHintTop.setTextColor(R.color.white);//设置颜色
        mBinding.tvClipHintTop.setTextSize(56);//设置文字大小
    }

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_consume;
    }

    public void updateMealInfoAndRefreshUi(@Nullable MealInfo result) {
        if (result == null || mMealInfo == result) {
            return;
        }
        mMealInfo = result;
        MealInfoUtil.initMealInfo(mMealInfo);

        isWhetherLimitWeightOfTake = mMealInfo.whetherLimitWeightOfTake == 1;
        clipWeight = new BigDecimal(mMealInfo.clipWeight);
        maxClipWeight = new BigDecimal(mMealInfo.clipWeight + 5);
        minClipWeight = new BigDecimal(mMealInfo.clipWeight - 5);
        updateMealInfoUi();
    }

    @SuppressLint("SetTextI18n")
    private void updateMealInfoUi() {
        if (mMealInfo == null || mBinding == null) {
            return;
        }
        mBinding.tvShowConsumeUnit.setText(mMealInfo.priceUnit);

        mBinding.tvFoodName.setText(mMealInfo.foodName);
        mBinding.tvFoodName2.setText(mMealInfo.foodName);
        String priceUnit = MealInfoUtil.getPriceFormat(FormatUtil.parseDouble(mMealInfo.price)) + " " + mMealInfo.priceUnit;
        String weightUnit = MealInfoUtil.getWeightUnit(mMealInfo);
        mBinding.tvPriceUnit.setText(priceUnit);
        mBinding.tvPriceUnit2.setText(priceUnit);
        mBinding.tvWeightUnit.setText(weightUnit);
        mBinding.tvWeightUnit2.setText(weightUnit);
        if (isWhetherLimitWeightOfTake) {
            mBinding.tvLimit.setVisibility(View.VISIBLE);
            mBinding.tvLimit.setText(String.format(Locale.CHINA, getString(R.string.text_limit), mMealInfo.limitWeightOfTake));
        } else {
            mBinding.tvLimit.setVisibility(View.GONE);
        }

        if (mMealInfo.recipeInfo != null) {
            mBinding.llNamePrice.setVisibility(View.VISIBLE);
            mBinding.tvFoodName2.setVisibility(View.GONE);
            mBinding.llPrice.setVisibility(View.GONE);
            mBinding.llBottom.setVisibility(View.VISIBLE);
            mBinding.tvBottomHint.setVisibility(View.VISIBLE);
            mBinding.tvEnergy.setText(R.string.text_heat_def);
            mBinding.tvProtein.setText(R.string.text_protein_def);
            mBinding.tvFat.setText(R.string.text_fat_def);
            mBinding.tvCarbohydrate.setText(R.string.text_carbohydrate_def);
        } else {
            mBinding.llBottom.setVisibility(View.GONE);
            mBinding.tvBottomHint.setVisibility(View.GONE);
            mBinding.llNamePrice.setVisibility(View.GONE);

            mBinding.tvFoodName2.setVisibility(View.VISIBLE);
            mBinding.llPrice.setVisibility(View.VISIBLE);
        }
    }


    public void setConsume(boolean isLocal, boolean timeout, String trayId, @Nullable GetConsumeResponse result) {
        if (!TextUtils.equals(trayId, this.mTrayId)) {
            settlement();
        }
        this.mTrayId = trayId;
        this.isLocal = isLocal;
        this.timeout = timeout;
        if (result != null) {
            mConsumeResponse = result;
        }
        updateConsumeUiAndInitPriceUI();
        LogUtil.d("setConsume isLocal:" + isLocal + "  timeout:" + timeout + "  trayId:" + trayId + "  result:" + result);
    }

    @SuppressLint("SetTextI18n")
    private void updateConsumeUiAndInitPriceUI() {
        if (mConsumeResponse == null) {
            return;
        }
        LogUtil.d("changeViewConsume");
        isWhetherLimitWeightOfTake = mConsumeResponse.whetherLimitWeightOfTake == 1;

        if (isLocal) {
            mBinding.tvAccountNo.setText(getSecurityTrayId(mConsumeResponse.accountNo));
        } else {
            if (YtdConfig.ConsumeModeOrder.equals(YtdConfig.getConsumeMode())) {
                //当为后支付模式时，不校验余额
                mBinding.tvAccountNo.setText(getSecurityTrayId(mTrayId));
            } else {
                mBinding.tvAccountNo.setText(FormatUtil.getSecurityNickName(mConsumeResponse.accountNo));
            }
        }
        mBinding.tvBalance.setText("¥" + MealInfoUtil.getPriceFormat(mConsumeResponse.balance));
        mBinding.tvTotalConsume.setText("¥" + MealInfoUtil.getPriceFormat(mConsumeResponse.totalConsume));
        if (mConsumeResponse.newUser) {
            LEDManager.getInstance().showBlue();
            LogUtil.d("LEDManager showBlue changeViewConsume");
        } else {
            LogUtil.d("LEDManager showGreen changeViewConsume");
            LEDManager.getInstance().showGreen();
        }
        mBinding.tvShowConsumeAmount.setText(MealInfoUtil.getPriceFormat(0.0d));
        mBinding.tvShowWeight.setText("(" + 0 + "g)");
        if (isWhetherLimitWeightOfTake) {
            mBinding.tvLimit.setVisibility(View.VISIBLE);
            mBinding.tvLimit.setText(String.format(Locale.CHINA, getString(R.string.text_limit), mConsumeResponse.limitWeightOfTake));
        } else {
            mBinding.tvLimit.setVisibility(View.GONE);
        }
    }

    public static String getSecurityTrayId(String trayId) {
        if (TextUtils.isEmpty(trayId)) {
            return "";
        }

        if (trayId.length() > 4) {
            return "*" + trayId.substring(trayId.length() - 4);
        } else {
            return trayId;
        }
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden) {//在首页
            if (mBinding != null) {
                mBinding.tvClipHintTop.stopRoll();
                mBinding.tvClipHintTop.setVisibility(View.INVISIBLE);
            }
            ConsumeWarnUtil.hide();
            settlement();
        } else {//消费页
            isTakeClip = false;
            if (mActivity.isAnomaly() && ConsumeWarnUtil.sAlarmWeight != null) {
                mStableWeight = BigDecimal.valueOf(ConsumeWarnUtil.sAlarmWeight.doubleValue());
                ConsumeWarnUtil.show(mConsumeResponse, isLocal, mStableWeight);
                mActivity.closeAnomaly();
                BigDecimal decimal = ScaleManager.getInstance().getStableWeight();
                BigDecimal subtract = decimal.subtract(mStableWeight).multiply(multiplyValue);
                BigDecimal change = mStableWeight.subtract(decimal).multiply(multiplyValue);
                checkClipWeight(subtract, change);
                updatePriceUi(decimal, true);
            } else {
                mStableWeight = ScaleManager.getInstance().getStableWeight();
                mTempWeight = mStableWeight;
                ConsumeWarnUtil.show(mConsumeResponse, isLocal, mStableWeight);
                updatePriceUi(mStableWeight, true);
            }
            ConsumeWarnUtil.sAlarmWeight = null;
            LogUtil.e("onHiddenChanged:开始重量：" + mStableWeight.doubleValue());
            startTime = System.currentTimeMillis();
            endTime = System.currentTimeMillis();

            calPriceStable = WeightConfig.getCalPriceStable();
            calPriceSub = WeightConfig.getCalPriceSub();
            calPriceTime = WeightConfig.getPriceCalTime();
        }
    }

    /**
     * 结算
     */
    public void settlement() {
        endTime = System.currentTimeMillis();
        if (mConsumeResponse == null) {
            return;
        }
        String userId = mConsumeResponse.userId;
        mConsumeResponse = null;
        if (mStableWeight == null || mMealInfo == null || TextUtils.isEmpty(mTrayId)) {
            return;
        }
        if (mTempWeight == null) {
            mTempWeight = mStableWeight;
        }
        int foodWeight = mStableWeight.subtract(mTempWeight).multiply(multiplyValue).intValue();
        if (foodWeight < 0) {
            foodWeight = 0;
        }
        OrderBean data = new OrderBean();
        data.trayId = mTrayId;
        data.foodWeight = String.valueOf(foodWeight);
        data.mealTimeId = mMealInfo.mealTimeId;
        data.startTime = FormatUtil.getDateFormat(new Date(startTime));
        data.endTime = FormatUtil.getDateFormat(new Date(endTime));
        data.userId = userId;
        ConsumeNetUtil.settlement(mMealInfo, data, isLocal, timeout);
        mTrayId = "";
    }

    public void refreshUi() {
        if (isHidden()) {
            return;
        }
        updateMealInfoUi();
        updateConsumeUiAndInitPriceUI();
        if (mTempWeight != null) {
            updatePriceUi(mTempWeight);
        }
    }

    /**
     * 秤稳定重量回调
     *
     * @param decimal 当前重量
     */
    public void onScaleStable(@Nullable BigDecimal decimal) {
        if (decimal == null || mActivity == null) {
            return;
        }
        if (isHidden()) {
            ConsumeWarnUtil.resultSneak(decimal, mActivity);
        } else {
            BigDecimal subtract = decimal.subtract(mTempWeight).multiply(multiplyValue);
            BigDecimal change = mStableWeight.subtract(decimal).multiply(multiplyValue);
            mActivity.runOnUiThread(() -> {
                checkClipWeight(subtract, change);
                updatePriceUi(decimal, true);
            });
        }
        mTempWeight = decimal;
    }

    private void checkClipWeight(@NonNull BigDecimal subtract, BigDecimal change) {
        if (clipWeight.compareTo(BigDecimal.ZERO) == 0) {
            isTakeClip = false;
            return;
        }
        LogUtil.d("TakeClip，weight subtract：" + subtract.intValue() + "--change：" + change.intValue());
        if (change.compareTo(minClipWeight) < 0) { //总变动是否小于 餐夹重量
            isTakeClip = false;
            LogUtil.d("TakeClip，false change.compareTo(minClipWeight)");
            return;
        }
        if (!isTakeClip) {//未拿起餐夹
            if (subtract.compareTo(BigDecimal.ZERO) < 0 && (subtract.abs().compareTo(minClipWeight) >= 0)) {
                LogUtil.d("TakeClip，true");
                isTakeClip = true;
            }
            return;
        }
        BigDecimal abs = subtract.abs();
        if (abs.compareTo(maxClipWeight) < 0 && (abs.compareTo(minClipWeight) >= 0)) {//大于餐夹重量，说明拿起了/放下了 餐夹
            LogUtil.d("TakeClip，subtract.abs().compareTo");
            if (subtract.compareTo(BigDecimal.ZERO) > 0) {
                LogUtil.d("TakeClip false");
                isTakeClip = false;
            }
        }
    }

    /**
     * 秤变化回调
     *
     * @param decimal 净重
     */
    public void onScaleChange(@Nullable BigDecimal decimal) {
        if (decimal == null || mActivity == null) {
            return;
        }
        if (isHidden()) {//在首页
            ConsumeWarnUtil.checkSneak(decimal);
        } else {//价格计算时机
            if (calPriceStable || System.currentTimeMillis() - calTime < calPriceTime) {
                //calPriceStable 是否仅计算稳定重量  calPriceTime 计算时间间隔
                return;
            }
            //calPriceSub 计算减重
            if (calPriceSub || decimal.subtract(mTempWeight).compareTo(BigDecimal.ZERO) <= 0) {
                calTime = System.currentTimeMillis();
                mActivity.runOnUiThread(() -> updatePriceUi(decimal));
            }
        }
    }

    @SuppressLint("SetTextI18n")
    private void updatePriceUi(@NonNull BigDecimal decimal, boolean isStable) {
        BigDecimal value = mStableWeight.subtract(decimal).multiply(multiplyValue);
        if (isTakeClip) {
            value = value.subtract(clipWeight);
        }
        if (value.compareTo(BigDecimal.ZERO) < 0) {
            value = BigDecimal.ZERO;
        }
        takeClip();
        int weight = value.intValue();
        updateRecipeInfo(weight);
        BigDecimal changePrice = MealInfoUtil.getChangePrice(mConsumeResponse, BigDecimal.valueOf(weight));
        mBinding.tvShowWeight.setText("(" + weight + "g)");
        String showConsumeAmount = MealInfoUtil.getPriceFormat(changePrice.doubleValue());
        mBinding.tvShowConsumeAmount.setText(showConsumeAmount);
        String totalConsume = getTotalConsume(changePrice);
        mBinding.tvTotalConsume.setText(totalConsume);

        if (isStable) {//稳定时检测弹窗
            ConsumeWarnUtil.checkWarn(mActivity, decimal, changePrice);
        }
    }

    /**
     * 处理餐夹
     */
    private void takeClip() {
        if (isTakeClip) {
            if (!isClipRoll) {
                LogUtil.d("TakeClip updatePriceUi isClipRoll： true");
                isClipRoll = true;
                mBinding.tvClipHintTop.setVisibility(View.VISIBLE);
                mBinding.tvClipHintTop.setTextDistance(30);
                mBinding.tvClipHintTop.setContent(getString(R.string.text_clip_hint));
                mBinding.tvClipHintTop.continueRoll();
            }
        } else {
            if (isClipRoll) {
                LogUtil.d("TakeClip updatePriceUi isClipRoll： false");
                mBinding.tvClipHintTop.stopRoll();
                mBinding.tvClipHintTop.setVisibility(View.INVISIBLE);
            }
            isClipRoll = false;
        }
    }

    @SuppressLint("SetTextI18n")
    private void updateRecipeInfo(int weight) {
        if (mMealInfo.recipeInfo == null) {
            return;
        }
        mBinding.llBottom.setVisibility(View.VISIBLE);
        mBinding.tvEnergy.setText(String.format(getString(R.string.text_heat), MealInfoUtil.getValueFormat(mMealInfo.recipeInfo.energy / 100 * weight)));
        mBinding.tvProtein.setText(String.format(getString(R.string.text_protein), MealInfoUtil.getValueFormat(mMealInfo.recipeInfo.protein / 100 * weight)));
        mBinding.tvFat.setText(String.format(getString(R.string.text_fat), MealInfoUtil.getValueFormat(mMealInfo.recipeInfo.fat / 100 * weight)));
        mBinding.tvCarbohydrate.setText(String.format(getString(R.string.text_carbohydrate), MealInfoUtil.getValueFormat(mMealInfo.recipeInfo.carbohydrate / 100 * weight)));
    }


    private void updatePriceUi(@NonNull BigDecimal decimal) {
        updatePriceUi(decimal, false);
    }


    private String getTotalConsume(BigDecimal changePrice) {
        String price;
        if (isLocal || mConsumeResponse == null) {
            price = "¥" + MealInfoUtil.getPriceFormat(changePrice.doubleValue());
        } else {
            BigDecimal result = changePrice.add(BigDecimal.valueOf(mConsumeResponse.totalConsume));
            price = "¥" + MealInfoUtil.getPriceFormat(result.doubleValue());
        }
        return price;
    }
}
